package controller

import (
	"context"
	"datum_user/dao"
	"datum_user/grpc"
	"datum_user/model"
	"datum_user/proto"
	"datum_user/utils"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"math/rand"
	"strconv"
	"time"
)

//获取验证码
func GetCode(c *gin.Context) {
	phone, ok := c.GetPostForm("phone")
	if !ok {
		ToJson(c, 201, "缺少参数phone", nil)
		return
	}
	//校验滑动验证码
	verifyId := c.PostForm("verify_id") //滑动验证码二次验证参数
	if ok, err := utils.SecondVerify(verifyId); !ok && err != nil {
		ToJson(c, 201, err.Error(), nil)
		return
	}
	//验证发送频率
	val, _ := dao.RedisClient.Get(phone + "register_sms").Result()
	if val == "exist" {
		ToJson(c, 201, "发送频率过快", nil)
		return
	}
	//判断手机号已注册否
	AesPhone, err := utils.EncyptogAES([]byte(phone))
	if err != nil {
		ToJson(c, 201, err.Error(), nil)
		return
	}
	var user model.User
	dao.Db.Where("phone = ?", hex.EncodeToString(AesPhone)).First(&user)
	if user.Id != 0 { //id != 0 则存在
		ToJson(c, 201, "此手机号已注册，请直接登录！", nil)
		return
	}
	//生成4位随机数验证码
	code := fmt.Sprintf("%04v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(10000))
	//发送短信
	req := proto.SendRegisterCodeRequest{Code: code,PhoneNumber: phone}
	_,err2 := grpc.GetSmsService().SendRegisterCode(context.Background(),&req)
	if err2 != nil {
		ToJson(c, 201, err2.Error(), nil)
	} else {
		err1 := dao.RedisClient.Set(phone, code, 5*time.Minute).Err()
		//设置此缓存是计算发送频率1分钟
		err2 := dao.RedisClient.Set(phone+"register_sms", "exist", 80*time.Second).Err()
		if err1 != nil || err2 != nil {
			ToJson(c, 201, "redis set fail", nil)
		} else {
			ToJson(c, 200, "ok", nil)
		}
	}
}

//检查验证码
func CheckCode(c *gin.Context) {
	phone := c.PostForm("phone")
	code := c.PostForm("code")
	val, err := dao.RedisClient.Get(phone).Result()
	if err != nil {
		ToJson(c, 201, err.Error(), nil)
	} else {
		if val != code {
			ToJson(c, 201, "验证码不正确", nil)
		} else {
			//用户输入正确,删除缓存的验证码
			dao.RedisClient.Del(phone)
			ToJson(c, 200, "ok", nil)
		}
	}
}

//创建用户信息
func CreateUser(c *gin.Context) {
	phone := c.PostForm("phone")
	password := c.PostForm("password")
	nickName := c.PostForm("nick_name")
	//对手机号进行加密
	AesPhone, err := utils.EncyptogAES([]byte(phone))
	if err != nil {
		ToJson(c, 201, err.Error(), nil)
		return
	}
	//生成随机头像url
	rand.Seed(time.Now().Unix())
	defaultAvatar := "https://cdn.ymkj8.com/datum/default_avatar/" + strconv.Itoa(rand.Intn(8)) + ".jpeg"
	//创建结构体数据
	user := model.User{
		Phone:    hex.EncodeToString(AesPhone),
		Password: password,
		Avatar:   defaultAvatar,
		NickName: nickName,
	}
	err = user.Create()
	if err != nil {
		ToJson(c, 201, err.Error(), nil)
	} else {
		//签发token
		req := proto.GetTokenRequest{Uid: uint32(user.Id)}
		res, err := grpc.GetTokenService().GetToken(context.Background(),&req)
		if err != nil {
			ToJson(c, 201, err.Error(), nil)
			return
		}
		ToJson(c, 200, "ok", map[string]interface{}{"user": user, "phone": phone, "token": res.Token})
	}
}
